import coin.exchange.base.kr_rest.private_client_base as privcb
import coin.exchange.bequant_v2.kr_rest.native_private_client as nprivc
from coin.exchange.bequant_v2.kr_rest.product import BequantProduct
from coin.exchange.bequant_v2.kr_rest.currency import BequantCurrency

from coin.proto.coin_query_pb2 import (AccountBalance, CurrencyBalance)


class BequantPrivateParser(object):
  @staticmethod
  def parse_balance(update_msg):
    # [
    #   {
    #     "currency": "ETH",
    #     "available": "10.000000000",
    #     "reserved": "0.560000000"
    #   },
    #   {
    #     "currency": "BTC",
    #     "available": "0.010205869",
    #     "reserved": "0"
    #   }
    # ]
    currency_balance_list = []
    currency_list = []
    for balance_info in update_msg:
      currency = BequantCurrency.FromStrNativeCurrencyNothrow(balance_info['currency'])
      if currency is None:
        continue
      available = float(balance_info['available'])
      hold = float(balance_info['reserved'])
      total = available + hold
      if currency in currency_list:
        index_num = currency_list.index(currency)
        currency_balance = currency_balance_list[index_num]
        currency_balance.hold += hold
        currency_balance.available += available
        currency_balance.total += total
        currency_balance_list[index_num] = currency_balance
      else:
        currency_list.append(currency)
        currency_balance = CurrencyBalance(
            currency=currency.currency,
            currency_native=currency.native_currency,
            available=available,
            hold=hold,
            total=total,
        )
        currency_balance_list.append(currency_balance)

    return AccountBalance(exchange='Bequant',
                          market_type='Spot',
                          each_balance=currency_balance_list)


class BequantPrivateClient(privcb.PrivateClientBase):
  ProductType = BequantProduct

  def __init__(self, key_file):
    privcb.PrivateClientBase.__init__(self)
    self.nprivc = nprivc.BequantNativePrivateClient(key_file=key_file)

  def query_account_balance_impl(self):
    update = self.nprivc._query_get_account_balance()
    update_trading_balance = self.nprivc._query_get_trading_balance()
    update.msg = update.msg + update_trading_balance.msg
    update.msg = BequantPrivateParser.parse_balance(update.msg)
    return update

  def query_fills_impl(self, product):
    raise NotImplementedError()

  def query_list_orders_impl(self, product):
    raise NotImplementedError()

  def query_submit_impl(self, product, side, price, qty):
    raise NotImplementedError()

  def query_cancel_product_impl(self, product):
    raise NotImplementedError()
